{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# to bring all functions that we have develop for marxan.\n",
    "%run marxan_utils.ipynb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "MARXAN_FOLDER = '/home/jovyan/work/datasets/raw/marxan_Tutorial/PracCONS7021/Marxan_backup'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input\t\t      MarOpt_v243_Linux64  output\t pu\n",
      "input.dat\t      Marxan.exe\t   output_100\t script.R\n",
      "MarOptTotalAreas.csv  Marxan_x64.exe\t   project1.zcp  scriptR.bat\n",
      "bound.dat  puvsp.dat\t      spec.csv\tspec.dat.backup_20200401T140605\n",
      "pu.dat\t   puvsp_sporder.dat  spec.dat\tspec.dat.backup_20200401T141514\n"
     ]
    }
   ],
   "source": [
    "# Help edit the .dat files\n",
    "!ls $MARXAN_FOLDER\n",
    "!ls $MARXAN_FOLDER/input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#JSON(conservationFeature.schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#json_schema = conservationFeature.schema_json()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples Read and write"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "VERSION 0.1\n",
      "BLM 0.1\n",
      "PROP 0.0\n",
      "RANDSEED -1\n",
      "NUMREPS 100\n",
      "BESTSCORE 0\n",
      "NUMITNS 0\n",
      "STARTTEMP 1\n",
      "COOLFAC 0\n",
      "NUMTEMP 1\n",
      "COSTTHRESH 0\n",
      "THRESHPEN1 0\n",
      "THRESHPEN2 0\n",
      "INPUTDIR input\n",
      "SPECNAME spec.dat\n",
      "PUNAME pu.dat\n",
      "PUVSPRNAME puvsp.dat\n",
      "BOUNDNAME bound.dat\n",
      "BLOCKDEFNAME blockdef.dat\n",
      "VERBOSITY 1\n",
      "MISSLEVEL 1\n",
      "OUTPUTDIR output\n",
      "SCENNAME Default_name\n",
      "SAVERUN 3\n",
      "SAVEBEST 3\n",
      "SAVESUMMARY 3\n",
      "SAVESCEN 3\n",
      "SAVETARGMET 3\n",
      "SAVESUMSOLN 3\n",
      "SAVELOG 1\n",
      "SAVESNAPSTEPS 0\n",
      "SAVESNAPCHANGES 0\n",
      "SAVESNAPFREQUENCY 0\n",
      "SAVESOLUTIONSMATRIX 3\n",
      "RUNMODE 1\n",
      "ITIMPTYPE 1\n",
      "HEURTYPE 1\n",
      "CLUMPTYPE 0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Create a new input.dat file with by default values\n",
    "test = DatFile()\n",
    "example = inputDatFile(BLM=0.1, NUMREPS =100, PUVSPRNAME= 'puvsp.dat')\n",
    "test.update(example.to_dat())\n",
    "print(test.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pu.dat\n",
      "bound.dat\n",
      "spec_notarget.dat\n",
      "puvsp.dat\n",
      "blockdef.dat\n"
     ]
    }
   ],
   "source": [
    "InputFile = DatFile(f'{MARXAN_FOLDER}/input.dat')\n",
    "InputFile.read()\n",
    "# InputFile.write(f'{MARXAN_FOLDER}/{MARXAN_INPUTDATA}')\n",
    "\n",
    "userInputFile = inputDatFile.from_dat(InputFile.data)\n",
    "print(userInputFile.PUNAME)\n",
    "print(userInputFile.BOUNDNAME)\n",
    "print(userInputFile.SPECNAME)\n",
    "print(userInputFile.PUVSPRNAME)\n",
    "print(userInputFile.BLOCKDEFNAME)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example marxan project"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Input File"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>VERSION</th>\n",
       "      <td>0.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BLM</th>\n",
       "      <td>0.02</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>PROP</th>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>RANDSEED</th>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NUMREPS</th>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BESTSCORE</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NUMITNS</th>\n",
       "      <td>1000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>STARTTEMP</th>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>COOLFAC</th>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NUMTEMP</th>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>COSTTHRESH</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>THRESHPEN1</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>THRESHPEN2</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>INPUTDIR</th>\n",
       "      <td>input</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SPECNAME</th>\n",
       "      <td>spec_notarget.dat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>PUNAME</th>\n",
       "      <td>pu.dat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>PUVSPRNAME</th>\n",
       "      <td>puvsp.dat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BOUNDNAME</th>\n",
       "      <td>bound.dat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BLOCKDEFNAME</th>\n",
       "      <td>blockdef.dat</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>VERBOSITY</th>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MISSLEVEL</th>\n",
       "      <td>0.95</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>OUTPUTDIR</th>\n",
       "      <td>output_100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SCENNAME</th>\n",
       "      <td>output</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVERUN</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVEBEST</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESUMMARY</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESCEN</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVETARGMET</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESUMSOLN</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVELOG</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESNAPSTEPS</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESNAPCHANGES</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESNAPFREQUENCY</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAVESOLUTIONSMATRIX</th>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>RUNMODE</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ITIMPTYPE</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>HEURTYPE</th>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CLUMPTYPE</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     0\n",
       "VERSION                            0.1\n",
       "BLM                               0.02\n",
       "PROP                               0.5\n",
       "RANDSEED                            -1\n",
       "NUMREPS                             10\n",
       "BESTSCORE                            0\n",
       "NUMITNS                        1000000\n",
       "STARTTEMP                           -1\n",
       "COOLFAC                             -1\n",
       "NUMTEMP                          10000\n",
       "COSTTHRESH                         0.0\n",
       "THRESHPEN1                         0.0\n",
       "THRESHPEN2                         0.0\n",
       "INPUTDIR                         input\n",
       "SPECNAME             spec_notarget.dat\n",
       "PUNAME                          pu.dat\n",
       "PUVSPRNAME                   puvsp.dat\n",
       "BOUNDNAME                    bound.dat\n",
       "BLOCKDEFNAME              blockdef.dat\n",
       "VERBOSITY                            2\n",
       "MISSLEVEL                         0.95\n",
       "OUTPUTDIR                   output_100\n",
       "SCENNAME                        output\n",
       "SAVERUN                              3\n",
       "SAVEBEST                             3\n",
       "SAVESUMMARY                          3\n",
       "SAVESCEN                             3\n",
       "SAVETARGMET                          3\n",
       "SAVESUMSOLN                          3\n",
       "SAVELOG                              3\n",
       "SAVESNAPSTEPS                        0\n",
       "SAVESNAPCHANGES                      0\n",
       "SAVESNAPFREQUENCY                    0\n",
       "SAVESOLUTIONSMATRIX                  3\n",
       "RUNMODE                              1\n",
       "ITIMPTYPE                            1\n",
       "HEURTYPE                            -1\n",
       "CLUMPTYPE                            0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{'VERSION': '0.1',\n",
       " 'BLM': 0.02,\n",
       " 'PROP': 0.5,\n",
       " 'RANDSEED': -1,\n",
       " 'NUMREPS': 10,\n",
       " 'BESTSCORE': 0,\n",
       " 'NUMITNS': 1000000,\n",
       " 'STARTTEMP': -1,\n",
       " 'COOLFAC': -1,\n",
       " 'NUMTEMP': 10000,\n",
       " 'COSTTHRESH': 0.0,\n",
       " 'THRESHPEN1': 0.0,\n",
       " 'THRESHPEN2': 0.0,\n",
       " 'INPUTDIR': 'input',\n",
       " 'SPECNAME': 'spec_notarget.dat',\n",
       " 'PUNAME': 'pu.dat',\n",
       " 'PUVSPRNAME': 'puvsp.dat',\n",
       " 'BOUNDNAME': 'bound.dat',\n",
       " 'BLOCKDEFNAME': 'blockdef.dat',\n",
       " 'VERBOSITY': 2,\n",
       " 'MISSLEVEL': 0.95,\n",
       " 'OUTPUTDIR': 'output_100',\n",
       " 'SCENNAME': 'output',\n",
       " 'SAVERUN': 3,\n",
       " 'SAVEBEST': 3,\n",
       " 'SAVESUMMARY': 3,\n",
       " 'SAVESCEN': 3,\n",
       " 'SAVETARGMET': 3,\n",
       " 'SAVESUMSOLN': 3,\n",
       " 'SAVELOG': 3,\n",
       " 'SAVESNAPSTEPS': 0,\n",
       " 'SAVESNAPCHANGES': 0,\n",
       " 'SAVESNAPFREQUENCY': 0,\n",
       " 'SAVESOLUTIONSMATRIX': 3,\n",
       " 'RUNMODE': 1,\n",
       " 'ITIMPTYPE': 1,\n",
       " 'HEURTYPE': -1,\n",
       " 'CLUMPTYPE': 0}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# read an existing input.dat file\n",
    "userInputFile\n",
    "\n",
    "#Static table\n",
    "# userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "# userInputFile_df.loc['BLM'] = 0.01\n",
    "# userInputFile_df\n",
    "# CreateFileFromDF(f'{MARXAN_FOLDER}/{MARXAN_INPUTDATA}',userInputFile_df,inputDatFile)\n",
    "\n",
    "\n",
    "# Interactive table ###\n",
    "userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "display(userInputFile_df)\n",
    "userInputFile.dict()\n",
    "#save_button(f'{MARXAN_FOLDER}/input.dat', inputDatFile, userInputFile_df)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[inputDatFile(VERSION='0.1', BLM=0.02, PROP=0.5, RANDSEED=-1, NUMREPS=10, BESTSCORE=0, NUMITNS=1000000, STARTTEMP=-1, COOLFAC=-1, NUMTEMP=10000, COSTTHRESH=0.0, THRESHPEN1=0.0, THRESHPEN2=0.0, INPUTDIR='input', SPECNAME='spec_notarget.dat', PUNAME='pu.dat', PUVSPRNAME='puvsp.dat', BOUNDNAME='bound.dat', BLOCKDEFNAME='blockdef.dat', VERBOSITY=2, MISSLEVEL=0.95, OUTPUTDIR='output_100', SCENNAME='output', SAVERUN=3, SAVEBEST=3, SAVESUMMARY=3, SAVESCEN=3, SAVETARGMET=3, SAVESUMSOLN=3, SAVELOG=3, SAVESNAPSTEPS=0, SAVESNAPCHANGES=0, SAVESNAPFREQUENCY=0, SAVESOLUTIONSMATRIX=3, RUNMODE=1, ITIMPTYPE=1, HEURTYPE=-1, CLUMPTYPE=0)]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "### MODIFICATION TO CHANGE PARAMETERSS\n",
    "## Modify for BLM calculations and save as new input.dat\n",
    "userInputFile.BLM = 0.02\n",
    "userInputFile.NUMREPS =10\n",
    "userInputFile.SPECNAME = 'spec_notarget.dat'\n",
    "\n",
    "userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "CreateFileFromDF(f'{MARXAN_FOLDER}/input.dat',userInputFile_df,inputDatFile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Planning units"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/home/jovyan/work/datasets/raw/marxan_Tutorial/PracCONS7021/Marxan_backup/input/pu.dat'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUNAME}'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>cost</th>\n",
       "      <th>status</th>\n",
       "      <th>xloc</th>\n",
       "      <th>yloc</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12173</th>\n",
       "      <td>12174</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12174</th>\n",
       "      <td>12175</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12175</th>\n",
       "      <td>12176</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12176</th>\n",
       "      <td>12177</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12177</th>\n",
       "      <td>12178</td>\n",
       "      <td>400.0</td>\n",
       "      <td>0</td>\n",
       "      <td>None</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>12178 rows × 5 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          id    cost  status  xloc  yloc\n",
       "0          1   400.0       0  None  None\n",
       "1          2   400.0       0  None  None\n",
       "2          3   400.0       0  None  None\n",
       "3          4   400.0       0  None  None\n",
       "4          5   400.0       0  None  None\n",
       "...      ...     ...     ...   ...   ...\n",
       "12173  12174  1080.0       0  None  None\n",
       "12174  12175   400.0       0  None  None\n",
       "12175  12176   400.0       0  None  None\n",
       "12176  12177   400.0       0  None  None\n",
       "12177  12178   400.0       0  None  None\n",
       "\n",
       "[12178 rows x 5 columns]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "userPlanningUnits = CreateListModelFromFile(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUNAME}', planningUnits)\n",
    "userPlanningUnits[:3]\n",
    "\n",
    "\n",
    "# #Static table\n",
    "# userPlanningUnits_df = pd.DataFrame([s.__dict__ for s in userPlanningUnits])\n",
    "# userPlanningUnits_df[0:3]\n",
    "# CreateFileFromDF(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUNAME}',userPlaningUnits_df,planningUnits)\n",
    "\n",
    "#Interactive table\n",
    "userPlanningUnits_df = pd.DataFrame([s.__dict__ for s in userPlanningUnits])\n",
    "display(userPlanningUnits_df)\n",
    "#save_button(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUNAME}', planningUnits, userPlanningUnits_df)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Conservation features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "userSpecData = CreateListModelFromFile(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.SPECNAME}', conservationFeature)\n",
    "\n",
    "#Static \n",
    "# userSpecData_df = pd.DataFrame([s.__dict__ for s in userSpecData])\n",
    "# userSpecData_df[0:3]\n",
    "# CreateFileFromDF(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.SPECNAME}',userSpecData_df,conservationFeature)\n",
    "\n",
    "#Intercative \n",
    "userSpecData_df = pd.DataFrame([s.__dict__ for s in userSpecData])\n",
    "display(userSpecData_df)\n",
    "#save_button(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.SPECNAME}', conservationFeature, userSpecData_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Planning units VS conservation features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>species</th>\n",
       "      <th>pu</th>\n",
       "      <th>amount</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37</td>\n",
       "      <td>1</td>\n",
       "      <td>470000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>39</td>\n",
       "      <td>1</td>\n",
       "      <td>3480000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>40</td>\n",
       "      <td>1</td>\n",
       "      <td>50000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>39</td>\n",
       "      <td>2</td>\n",
       "      <td>4000000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>37</td>\n",
       "      <td>3</td>\n",
       "      <td>10000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36854</th>\n",
       "      <td>46</td>\n",
       "      <td>12176</td>\n",
       "      <td>60000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36855</th>\n",
       "      <td>47</td>\n",
       "      <td>12176</td>\n",
       "      <td>20000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36856</th>\n",
       "      <td>3</td>\n",
       "      <td>12177</td>\n",
       "      <td>120000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36857</th>\n",
       "      <td>41</td>\n",
       "      <td>12177</td>\n",
       "      <td>640000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36858</th>\n",
       "      <td>41</td>\n",
       "      <td>12178</td>\n",
       "      <td>240000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>36859 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       species     pu     amount\n",
       "0           37      1   470000.0\n",
       "1           39      1  3480000.0\n",
       "2           40      1    50000.0\n",
       "3           39      2  4000000.0\n",
       "4           37      3    10000.0\n",
       "...        ...    ...        ...\n",
       "36854       46  12176    60000.0\n",
       "36855       47  12176    20000.0\n",
       "36856        3  12177   120000.0\n",
       "36857       41  12177   640000.0\n",
       "36858       41  12178   240000.0\n",
       "\n",
       "[36859 rows x 3 columns]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# this is the vertical file; for the horizontal one this needs to change a bit\n",
    "userPuvsp2Data = CreateListModelFromFile(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUVSPRNAME}', planningUnitVSConservationFeatureV)\n",
    "\n",
    "#Static\n",
    "# userPuvsp2Data_df = pd.DataFrame([s.__dict__ for s in userPuvsp2Data])\n",
    "# userPuvsp2Data_df[0:3]\n",
    "\n",
    "#Intercative\n",
    "userPuvsp2Data_df = pd.DataFrame([s.__dict__ for s in userPuvsp2Data])\n",
    "display(userPuvsp2Data_df)\n",
    "#save_button(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.PUVSPRNAME}', planningUnitVSConservationFeatureV, userPuvsp2Data_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Boundary Length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id1</th>\n",
       "      <th>id2</th>\n",
       "      <th>boundary</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>4000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>73</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25103</th>\n",
       "      <td>12175</td>\n",
       "      <td>12176</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25104</th>\n",
       "      <td>12176</td>\n",
       "      <td>12176</td>\n",
       "      <td>4000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25105</th>\n",
       "      <td>12177</td>\n",
       "      <td>12177</td>\n",
       "      <td>4000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25106</th>\n",
       "      <td>12177</td>\n",
       "      <td>12178</td>\n",
       "      <td>2000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25107</th>\n",
       "      <td>12178</td>\n",
       "      <td>12178</td>\n",
       "      <td>4000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>25108 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         id1    id2  boundary\n",
       "0          1      1    4000.0\n",
       "1          1      2    2000.0\n",
       "2          1     73    2000.0\n",
       "3          2      2    2000.0\n",
       "4          2      3    2000.0\n",
       "...      ...    ...       ...\n",
       "25103  12175  12176    2000.0\n",
       "25104  12176  12176    4000.0\n",
       "25105  12177  12177    4000.0\n",
       "25106  12177  12178    2000.0\n",
       "25107  12178  12178    4000.0\n",
       "\n",
       "[25108 rows x 3 columns]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "userBoundData = CreateListModelFromFile(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.BOUNDNAME}', boundaryLength)\n",
    "\n",
    "#Static\n",
    "# userBoundData_df = pd.DataFrame([s.__dict__ for s in userBoundData])\n",
    "# userBoundData_df[0:3]\n",
    "\n",
    "#Interactive\n",
    "userBoundData_df = pd.DataFrame([s.__dict__ for s in userBoundData])\n",
    "display(userBoundData_df)\n",
    "#save_button(f'{MARXAN_FOLDER}/{userInputFile.INPUTDIR}/{userInputFile.BOUNDNAME}', boundaryLength, userBoundData_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Execute Marxan"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "MARXAN_FOLDER = '/home/jovyan/work/datasets/raw/marxan_Coral_Triangle_Case_Study'\n",
    "MARXAN_EXECUTABLE = f'{MARXAN_FOLDER}/MarOpt_v243_Linux64'\n",
    "MARXAN_INPUTDATA = 'input.dat'\n",
    "InputFile = DatFile(f'{MARXAN_FOLDER}/{MARXAN_INPUTDATA}')\n",
    "InputFile.read()\n",
    "userInputFile = inputDatFile.from_dat(InputFile.data)\n",
    "# userInputFile.BLM = blm\n",
    "# userInputFile.OUTPUTDIR =f'output_{blm}'\n",
    "# userInputFile.NUMREPS =10\n",
    "# userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "# CreateFileFromDF(f'{MARXAN_FOLDER}/{MARXAN_INPUTDATA}',userInputFile_df,inputDatFile)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.mkdir(f'{MARXAN_FOLDER}/{userInputFile.OUTPUTDIR}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Marxan v 2.43\n",
      "Marxan v 2.43\n",
      "Marxan v 2.43\n",
      "Marxan v 2.43\n",
      "Marxan v 2.43\n",
      "Marxan v 2.43\n",
      "\n"
     ]
    }
   ],
   "source": [
    "MARXAN_FOLDER = '/home/jovyan/work/datasets/raw/marxan_Tutorial/PracCONS7021/Marxan_backup'\n",
    "\n",
    "for blm in [0.001,0.01,0.1,1,10,100]:\n",
    "    InputFile = DatFile(f'{MARXAN_FOLDER}/input.dat')\n",
    "    InputFile.read()\n",
    "    userInputFile = inputDatFile.from_dat(InputFile.data)\n",
    "    \n",
    "    ## Modify for BLM calculations and save as new input.dat\n",
    "    userInputFile.BLM = blm\n",
    "    userInputFile.OUTPUTDIR =f'output_{blm}'\n",
    "    userInputFile.NUMREPS =10\n",
    "    \n",
    "    userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "    userInputFile_df = pd.DataFrame.from_dict(userInputFile.__dict__, orient='index')\n",
    "    userInputFile_df= userInputFile_df.drop('BLOCKDEFNAME')\n",
    "\n",
    "    CreateFileFromDF(f'{MARXAN_FOLDER}/input.dat',userInputFile_df,inputDatFile)\n",
    "    \n",
    "    execute_marxan(MARXAN_FOLDER)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/work/datasets/raw/marxan_Tutorial/PracCONS7021/Marxan_backup/output_100\n"
     ]
    }
   ],
   "source": [
    "print(f'{MARXAN_FOLDER}/{userInputFile.OUTPUTDIR}')\n",
    "if os.path.exists(f'{MARXAN_FOLDER}/{userInputFile.OUTPUTDIR}'):\n",
    "    rmtree(f'{MARXAN_FOLDER}/{userInputFile.OUTPUTDIR}')\n",
    "os.mkdir(f'{MARXAN_FOLDER}/{userInputFile.OUTPUTDIR}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Marxan v 2.43\n"
     ]
    }
   ],
   "source": [
    "MARXAN_FOLDER = '/home/jovyan/work/datasets/raw/marxan_Tutorial/PracCONS7021/Marxan_backup'\n",
    "\n",
    "\n",
    "#EXECUTES MARXAN\n",
    "# Needs to execute marxan from the marxan root folder in order to make the file find the required data.\n",
    "execute_marxan(MARXAN_FOLDER)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Postprocess Output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This are the validation data types that we need to produce before ingesting it in the DB.  \n",
    "Next step will connect to both DB and will extract the tables we require and generate pydantic models from them. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sqlalchemy import create_engine, MetaData\n",
    "from sqlalchemy.ext.automap import automap_base\n",
    "from sa2schema.to.pydantic import sa_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "JSON(sa_model(apiBase.classes.users).schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py:3198: SAWarning: Did not recognize type 'geometry' of column 'extent'\n",
      "  util.warn(\n",
      "/opt/conda/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py:3528: SAWarning: Skipped unsupported reflection of expression-based index unique_user_emails\n",
      "  util.warn(\n",
      "/opt/conda/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py:3528: SAWarning: Skipped unsupported reflection of expression-based index unique_organization_names\n",
      "  util.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['public.output_results', 'public.scenarios', 'public.users', 'public.projects', 'public.organizations'])\n"
     ]
    },
    {
     "data": {
      "application/json": {
       "additionalProperties": false,
       "description": "Base for SqlAlchemy models.\n\nThis model will brutely load all unloaded attributes, even if that triggers hundreds of additional SQL queries.\n\nWhen encountering recursive relationships, it will replace their recursive values with `None`. Make sure your schema is ready for that.\nUse it with `make_optional`; that's the best thing.",
       "properties": {
        "connectivity": {
         "title": "Connectivity",
         "type": "number"
        },
        "connectivity_total": {
         "title": "Connectivity Total",
         "type": "number"
        },
        "cost": {
         "title": "Cost",
         "type": "number"
        },
        "id": {
         "title": "Id"
        },
        "metadata": {
         "title": "Metadata",
         "type": "object"
        },
        "missing_values": {
         "title": "Missing Values",
         "type": "number"
        },
        "mpm": {
         "title": "Mpm",
         "type": "number"
        },
        "penalty": {
         "title": "Penalty",
         "type": "number"
        },
        "planning_units": {
         "title": "Planning Units",
         "type": "number"
        },
        "run_id": {
         "title": "Run Id",
         "type": "integer"
        },
        "scenarios_id": {
         "title": "Scenarios Id"
        },
        "score": {
         "title": "Score",
         "type": "number"
        },
        "shortfall": {
         "title": "Shortfall",
         "type": "number"
        }
       },
       "required": [
        "id"
       ],
       "title": "output_results",
       "type": "object"
      },
      "text/plain": [
       "<IPython.core.display.JSON object>"
      ]
     },
     "execution_count": 12,
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "root"
      }
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "api_engine = create_engine(f\"postgres://marxan-api:marxan-api@marxan-postgresql-api:5432/marxan-api\")\n",
    "api_meta = MetaData(schema=\"public\")\n",
    "api_meta.reflect(bind=api_engine, only=['output_results'])\n",
    "print(api_meta.tables.keys())\n",
    "apiBase = automap_base(metadata=api_meta)\n",
    "apiBase.prepare()\n",
    "#mapped classes are ready\n",
    "OutputResults = sa_model(apiBase.classes.output_results) #classes: output_results, scenarios, projects, organizations, users\n",
    "JSON(OutputResults.schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py:3198: SAWarning: Did not recognize type 'geometry' of column 'the_geom'\n",
      "  util.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['public.spatial_ref_sys', 'public.migrations', 'public.admin_regions', 'public.admin_regions_0', 'public.admin_regions_1', 'public.admin_regions_2', 'public.wdpa', 'public.features_data', 'public.scenario_features_data', 'public.planning_units_geom', 'public.planning_units_geom_square', 'public.planning_units_geom_hexagon', 'public.planning_units_geom_irregular', 'public.scenarios_pu_data', 'public.scenarios_pu_cost_data', 'public.output_results_data'])\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.8/site-packages/IPython/core/display.py:904: UserWarning: JSON expects JSONable dict or list, not JSON strings\n",
      "  warnings.warn(\"JSON expects JSONable dict or list, not JSON strings\")\n"
     ]
    },
    {
     "data": {
      "application/json": {
       "additionalProperties": false,
       "description": "Base for SqlAlchemy models.\n\nThis model will brutely load all unloaded attributes, even if that triggers hundreds of additional SQL queries.\n\nWhen encountering recursive relationships, it will replace their recursive values with `None`. Make sure your schema is ready for that.\nUse it with `make_optional`; that's the best thing.",
       "properties": {
        "id": {
         "title": "Id"
        },
        "missing_values": {
         "title": "Missing Values",
         "type": "object"
        },
        "puid": {
         "title": "Puid",
         "type": "integer"
        },
        "run_id": {
         "title": "Run Id"
        },
        "scenario_id": {
         "title": "Scenario Id"
        },
        "value": {
         "title": "Value",
         "type": "number"
        }
       },
       "required": [
        "id"
       ],
       "title": "output_results_data",
       "type": "object"
      },
      "text/plain": [
       "<IPython.core.display.JSON object>"
      ]
     },
     "execution_count": 7,
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "root"
      }
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_api_engine = create_engine(f\"postgres://marxan-geo-api:marxan-geo-api@marxan-postgresql-geo-api:5432/marxan-geo-api\")\n",
    "geo_api_meta = MetaData(schema=\"public\")\n",
    "geo_api_meta.reflect(bind=geo_api_engine)\n",
    "print(geo_api_meta.tables.keys())\n",
    "geoApiBase = automap_base(metadata=geo_api_meta)\n",
    "geoApiBase.prepare()\n",
    "#mapped classes are ready\n",
    "OutputResultsData = sa_model(geoApiBase.classes.output_results_data)\n",
    "JSON(OutputResultsData.schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": {
       "additionalProperties": false,
       "description": "Base for SqlAlchemy models.\n\nThis model will brutely load all unloaded attributes, even if that triggers hundreds of additional SQL queries.\n\nWhen encountering recursive relationships, it will replace their recursive values with `None`. Make sure your schema is ready for that.\nUse it with `make_optional`; that's the best thing.",
       "properties": {
        "feature_id": {
         "title": "Features Id"
        },
        "id": {
         "title": "Id"
        },
        "properties": {
         "title": "Properties",
         "type": "object"
        },
        "source": {
         "title": "Source",
         "type": "string"
        },
        "the_geom": {
         "title": "The Geom"
        }
       },
       "required": [
        "id"
       ],
       "title": "features_data",
       "type": "object"
      },
      "text/plain": [
       "<IPython.core.display.JSON object>"
      ]
     },
     "execution_count": 13,
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "root"
      }
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "OutputResultsData = sa_model(geoApiBase.classes.features_data)\n",
    "JSON(OutputResultsData.schema_json())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once the models for validation are ready we can use the same rules we had above to load / save from pandas. `CreateFileFromDF(filename: str, df: Type['Dataframe'], model: Type['Model'])`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "CreateFileFromDF(filename: str, df: Type['Dataframe'], model=OutputResultsData)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#CreateFileFromDF(filename: str, df: Type['Dataframe'], model=OutputResults)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "scenario_features_data"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sa_model(geoApiBase.classes.scenario_features_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "OutputResultsData = sa_model(geoApiBase.classes.scenario_features_data)\n",
    "JSON(OutputResultsData.schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.8/site-packages/IPython/core/display.py:904: UserWarning: JSON expects JSONable dict or list, not JSON strings\n",
      "  warnings.warn(\"JSON expects JSONable dict or list, not JSON strings\")\n"
     ]
    },
    {
     "data": {
      "application/json": {
       "additionalProperties": false,
       "description": "Base for SqlAlchemy models.\n\nThis model will brutely load all unloaded attributes, even if that triggers hundreds of additional SQL queries.\n\nWhen encountering recursive relationships, it will replace their recursive values with `None`. Make sure your schema is ready for that.\nUse it with `make_optional`; that's the best thing.",
       "properties": {
        "id": {
         "title": "Id"
        },
        "missing_values": {
         "title": "Missing Values",
         "type": "object"
        },
        "puid": {
         "title": "Puid",
         "type": "integer"
        },
        "run_id": {
         "title": "Run Id"
        },
        "scenario_id": {
         "title": "Scenario Id"
        },
        "value": {
         "title": "Value",
         "type": "number"
        }
       },
       "required": [
        "id"
       ],
       "title": "output_results_data",
       "type": "object"
      },
      "text/plain": [
       "<IPython.core.display.JSON object>"
      ]
     },
     "execution_count": 17,
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "root"
      }
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "OutputResultsData = sa_model(geoApiBase.classes.output_results_data)\n",
    "JSON(OutputResultsData.schema_json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
